const fs = require('fs');
const path = require('path');
const readline = require('readline');
const { Sequelize } = require('sequelize')


var dbhost, dbname, dbuser, dbpassword;
function copyFolder(_fromfolder, _tofolder) {
    // 检查源文件夹是否存在
    if (!fs.existsSync(_fromfolder)) {
        console.error(`源文件夹 ${_fromfolder} 不存在`);
        return;
    }
    // 创建目标文件夹
    if (!fs.existsSync(_tofolder)) {
        fs.mkdirSync(_tofolder, { recursive: true });
    }
    // 读取源文件夹中的所有文件和子文件夹
    const files = fs.readdirSync(_fromfolder);
    files.forEach((file) => {
        const fromPath = path.join(_fromfolder, file);
        const toPath = path.join(_tofolder, file);
        const stat = fs.statSync(fromPath);
        if (stat.isDirectory()) {
            // 如果是文件夹，则递归复制
            copyFolder(fromPath, toPath);
        } else {
            // 如果是文件，则复制文件
            fs.copyFileSync(fromPath, toPath);
        }
    });
}
// 执行命令行命令
function runCommand(cmd) {
    return new Promise((resolve, reject) => {
        const childProcess = require('child_process');
        childProcess.exec(cmd, (error, stdout, stderr) => {
            if (error) {
                reject(error);
            } else {
                resolve(stdout);
            }
        });
    });
}

function generateDBModel() {
    return new Promise((resolve, reject) => {
        console.log('Step2 生成数据库模型 begin ');
        const rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout
        });

        rl.question('请输入数据库地址: ', (host) => {
            dbhost = host;
            rl.question('请输入数据库名: ', (database) => {
                dbname = database;
                rl.question('请输入数据库用户名: ', (user) => {
                    dbuser = user;
                    rl.question('请输入数据库密码: ', (password) => {
                        dbpassword = password;
                        rl.close();
                        const cmd = `cd ./project/apiserver && npx sequelize-auto -h ${host} -d ${database} -u ${user} -x ${password} -p 3306`;
                        runCommand(cmd)
                            .then((stdout) => {
                                console.log('命令执行成功:', stdout);
                                resolve();
                                console.log('Step2 生成数据库模型 end ');
                                copyFolder('./project/apiserver/models', './project/eggserver/app/models');
                                console.log('Step2 复制eggserver/models文件夹 end ');
                            })
                            .catch((error) => {
                                console.error('命令执行失败:', error);
                                reject(error);
                            });
                    });
                });
            });
        });
    });
}

async function init() {
    //step1-1:复制server文件夹 
    console.log('Step1-1 复制server文件夹 begin ');
    copyFolder('./tpl/serverapi_tpl', './project/apiserver');
    console.log('Step1-1 复制server文件夹 end ');

    console.log('Step1-1 复制server文件夹 begin ');
    copyFolder('./tpl/eggserver_tpl', './project/eggserver');
    console.log('Step1-1 复制server文件夹 end ');

    //step1-2:复制admin文件夹
    console.log('Step1-2 复制admin文件夹 begin ');
    copyFolder('./tpl/admin_tpl', './project/admin');
    console.log('Step1-2 复制admin文件夹 end ');
    //step1-3:复制前端文件夹
    console.log('Step1-3 复制前端文件夹 begin ');
    copyFolder('./tpl/uniapp_tpl', './project/frontend');
    console.log('Step1-3 复制前端文件夹 end ');

    // step2: 生成数据库模型
    try {
        await generateDBModel();

        generateEggServer();

        // step3: 根据数据库模型，生成接口，admin页面，并写入对应文件夹  
        console.log('Step3 循环表，增加对应的server API请求和admin页面和api请求方法，并拼接路由配置 begin ');
        //step3.1 读取model
        var files = fs.readdirSync('./project/apiserver/models');
        var routerconfig = '';

        var unipagesconfig = '';

        const sequelize = new Sequelize(dbname, dbuser, dbpassword, {
            host: dbhost,
            dialect: 'mysql'
        })
        const DataTypes = require("sequelize").DataTypes;
        // 循环表，增加对应的server API请求和admin页面和api请求方法，并拼接路由配置
        files.forEach(file => {
            if (file == 'init-models.js') {
                console.log('跳过init-models.js');
            } else {
                var _file = './project/apiserver/models/' + file;



                var _obj = require(_file);
                var obj = _obj(sequelize, DataTypes);
                //step 3.2 生成接口               
                generateRouter('./project/apiserver/routes/', dbhost, dbname, dbuser, dbpassword, obj.tableName, obj.primaryKeyAttributes[0]);
                //step 3.3 生成admin页面
                generateAdmin('./project/admin/', obj);
                //增加页面的路由配置

                var routerObjStr = `{
                    path: "/$Table_Name",
                    component: Layout,
                    redirect: "/$Table_Name/list",
                    name: "$Table_Name",
                    meta: {
                        title: "$Table_Name管理",
                        icon: "eye-open"
                    },
                    children: [
                        {
                            path: "add",
                            component: () => import('@/views/$Table_Name/add'),
                            name: "Add$Table_Name",
                            meta: { title: "发布$Table_Name", icon: "edit" }
                        },
                        {
                            path: "list",
                            component: () => import('@/views/$Table_Name/list'),
                            name: "$Table_NameList",
                            meta: { title: "$Table_Name列表", icon: "list" }
                        },
                        {
                            path: "edit/:id(\\\\d+)",
                            component: () => import('@/views/$Table_Name/edit'),
                            name: "Edit$Table_Name",
                            meta: {
                                title: "编辑$Table_Name",
                                noCache: true,
                                activeMenu: "/$Table_Name/list" // 激活菜单显示在列表页
                            },
                            hidden: true // 在侧边栏中隐藏
                        }
                    ]
                },`;
                routerconfig += routerObjStr.replace(/\$Table_Name/g, obj.tableName) ;


                //pages.json 增加页面
                unipagesconfig += `,{
                    "path": "pages/${obj.tableName}/add",
                    "style": {
                        "navigationBarTitleText": "uni-app"
                    }
                },{
                    "path": "pages/${obj.tableName}/edit",
                    "style": {
                        "navigationBarTitleText": "uni-app"
                    }
                },{
                    "path": "pages/${obj.tableName}/list",
                    "style": {
                        "navigationBarTitleText": "uni-app"
                    }
                }`;


                generateFrontend('./project/frontend/', obj);

            }

        });
        //step3.4 admin部分写入路由配置
        replaceContent('./project/admin/src/router/index.js', /\$--ROUTERMAPS--\$/g, routerconfig);
        //step3.5 frontend 部分写入pages.json
        replaceContent('./project/frontend/pages.json', /\$--PAGESCONFIG--\$/g, unipagesconfig);



        console.log('Step3 循环表，增加对应的server API请求和admin页面和api请求方法，并拼接路由配置 end ');
    } catch (error) {
        console.error('初始化过程中出现错误:', error);
    }
}


function generateEggServer() {
    console.log('Step4 生成eggserver 配置 begin ');
    //读取models
    var files = fs.readdirSync('./project/eggserver/app/models');
    const sequelize = new Sequelize(dbname, dbuser, dbpassword, {
        host: dbhost,
        dialect: 'mysql'
    })
    const DataTypes = require("sequelize").DataTypes;
    var routerconfig = '';
    //替换dbconfig
    replaceContent('./project/eggserver/app/models/dbconfig.js', /\$DB_NAME\$/g, dbname);
    replaceContent('./project/eggserver/app/models/dbconfig.js', /\$DB_USER\$/g, dbuser);
    replaceContent('./project/eggserver/app/models/dbconfig.js', /\$DB_PWD\$/g, dbpassword);
    replaceContent('./project/eggserver/app/models/dbconfig.js', /\$DB_HOST\$/g, dbhost);
    // 循环表，增加对应的server API请求和admin页面和api请求方法，并拼接路由配置
    files.forEach(file => {
        if (file == 'init-models.js' || file == 'dbconfig.js') {
            console.log('跳过init-models.js 和 dbconfig.js');
        } else {
            var _file = './project/eggserver/app/models/' + file;
            var _obj = require(_file);
            var obj = _obj(sequelize, DataTypes);
            var tableName = obj.tableName;
            var primarykey = obj.primaryKeyAttributes[0];
            generateEggAPI(dbhost, dbname, dbuser, dbpassword, tableName,primarykey);
            routerconfig += ` router.get('/${tableName}/list', controller.${tableName}.list);
            router.post('/${tableName}/add', controller.${tableName}.add);
            router.post('/${tableName}/update', controller.${tableName}.update);
            router.get('/${tableName}/delete', controller.${tableName}.del);
            router.get('/${tableName}/get', controller.${tableName}.get);
            `;
        }
    })
    console.log('routerconfig:' + routerconfig);
    replaceContent('./project/eggserver/app/router.js', /\$ROUTERCFG\$/g, routerconfig);

    console.log('Step4 生成eggserver 配置 end ');
}

function generateEggAPI(dbhost, dbname, dbuser, dbpassword, tableName,primarykey) {
    console.log(tableName + 'EGG-Server配置 生成  begin ');
    //生成 eggserver 接口api请求

    // 生成service 
    fs.copyFileSync('./project/eggserver/app/service/servicejs.tpl', './project/eggserver/app/service/' + tableName + '.js');
    // 替换文件名
    
    replaceContent('./project/eggserver/app/service/' + tableName + '.js', /\$TABLE_NAME\$/g, tableName);
    replaceContent('./project/eggserver/app/service/' + tableName + '.js', /\$PRIMARYKEY\$/g, primarykey);

    // 生成controller
    fs.copyFileSync('./project/eggserver/app/controller/controllerjs.tpl', './project/eggserver/app/controller/' + tableName + '.js');
    // 替换文件名
    replaceContent('./project/eggserver/app/controller/' + tableName + '.js', /\$TABLE_NAME\$/g, tableName); //替换表名
    replaceContent('./project/eggserver/app/controller/' + tableName + '.js', /\$PRIMARYKEY\$/g, primarykey);//替换主键

    console.log(tableName + 'EGG-Server配置 生成  end ');
}

function generateAdmin(_adminfolder, _modle) {
    console.log(_modle.tableName + '相关admin配置 生成  begin ');
    var primarykey = _modle.primaryKeyAttributes[0];
    var tableName = _modle.tableName;
    //生成 admin后台的 接口api请求
    //copy 文件
    fs.copyFileSync(_adminfolder + '/src/api/apijs.tpl', _adminfolder + 'src/api/' + tableName + '.js');
    // 生成对应API请求
    replaceContent(_adminfolder + 'src/api/' + tableName + '.js', /\$TABLENAME\$/g, tableName);
    replaceContent(_adminfolder +'src/api/' + tableName + '.js', /\$PRIMARYKEY\$/g, primarykey);
    //生成admin后台的页面
    copyFolder(_adminfolder + 'src/views/adminviewsfolder_tpl/', _adminfolder + 'src/views/' + tableName + '/');
    // 替换form属性 
    var attributes = _modle.getAttributes();
    var formstructs = '';
    var formitems = '';
    var listcolumns = '';
    for (var key in attributes) {
        var attribute = attributes[key];
        var type = attribute.type;
        var field = attribute.field;
        var comment = attribute.comment;
        // form 结构
        formstructs += field + ':"",\n'

        // form item 结构
        var label = attribute.comment ? attribute.comment : field;
        if (field == primarykey) {
            formitems += '<el-form-item label="' + label + '">' +
                '<el-input readonly v-model="form.' + field + '"/></el-form-item>' +
                '\n';
        } else {
            formitems += '<el-form-item label="' + label + '">' +
                '<el-input v-model="form.' + field + '"/></el-form-item>' +
                '\n';
        }


        // list 结构
        listcolumns += '<el-table-column prop="' + field + '" label="' + label + '"></el-table-column>';

    }
    //增加
    replaceContent(_adminfolder + 'src/views/' + tableName + '/add.vue', /\$--FORMATTRIBUTE--\$/g, formstructs);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/add.vue', /\$--FORMITEM--\$/g, formitems);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/add.vue', /\$TABLENAME\$/g, tableName);

    //编辑
    replaceContent(_adminfolder + 'src/views/' + tableName + '/edit.vue', /\$--FORMATTRIBUTE--\$/g, formstructs);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/edit.vue', /\$--FORMITEM--\$/g, formitems);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/edit.vue', /\$TABLENAME\$/g, tableName);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/edit.vue', /\$primary\$/g, primarykey);


    //列表
    replaceContent(_adminfolder + 'src/views/' + tableName + '/list.vue', /\$--LISTCOLUMN--\$/g, listcolumns);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/list.vue', /\$TABLENAME\$/g, tableName);
    replaceContent(_adminfolder + 'src/views/' + tableName + '/list.vue', /\$primary\$/g, primarykey);



    console.log(_modle.tableName + '相关admin配置 生成 end');
}

function generateFrontend(_folder, _modle) {
    console.log('生成前端页面 begin ');
    //复制前端页面模版
    copyFolder(_folder + 'pages/unifolder_tpl/', _folder + 'pages/' + _modle.tableName + '/');

    //替换页面内容
    var primarykey = _modle.primaryKeyAttributes[0];
    var tableName = _modle.tableName;
    var attributes = _modle.getAttributes();
    var formstructs = '';
    var unilisteitems = '';
    var formitems = '';

    for (var key in attributes) {
        var attribute = attributes[key];
        var type = attribute.type;
        var field = attribute.field;
        var label = attribute.comment ? attribute.comment : field;
        formstructs += field + ':"",\n'
        unilisteitems += '<view>' + label + ':{{item.' + field + '}}</view>' + '\n';
        if (field == primarykey) {
            formitems += '<uni-forms-item label="' + label + '" name="' + field + '">\n'+label+':<input readonly type="text" v-model="form.' + field + '" />\n</uni-forms-item>' + '\n';
        } else {
            formitems += '<uni-forms-item label="' + label + '" name="' + field + '">\n'+label+':<input type="text" v-model="form.' + field + '" placeholder="请输入' + label + '" />\n</uni-forms-item>' + '\n';
        }
    }

    //替换list页内容
    replaceContent(_folder + 'pages/' + _modle.tableName + '/list.vue', /\$-LISTITEM-\$/g, unilisteitems);
    replaceContent(_folder + 'pages/' + _modle.tableName + '/list.vue', /\$-TABLENAME-\$/g, tableName);
    //替换edit页内容
    replaceContent(_folder + 'pages/' + _modle.tableName + '/edit.vue', /\$-FORMITEM-\$/g, formitems);
    replaceContent(_folder + 'pages/' + _modle.tableName + '/edit.vue', /\$-TABLENAME-\$/g, tableName);
    replaceContent(_folder + 'pages/' + _modle.tableName + '/edit.vue', /\$-FORMSTRUCT-\$/g, formstructs);
    //替换add页内容
    replaceContent(_folder + 'pages/' + _modle.tableName + '/add.vue', /\$-FORMITEM-\$/g, formitems);
    replaceContent(_folder + 'pages/' + _modle.tableName + '/add.vue', /\$-TABLENAME-\$/g, tableName);
    replaceContent(_folder + 'pages/' + _modle.tableName + '/add.vue', /\$-FORMSTRUCT-\$/g, formstructs);
    console.log('生成前端页面 end ');
}

function generateRouter(_routerfolder, dbhost, dbname, dbuser, dbpassword, tableName, primarykey) {
    console.log('生成crud接口 begin ');
    console.log(tableName, primarykey);
    const path = require('path');

    // 读取 router.tpl 文件内容
    const templatePath = path.join(_routerfolder, 'router.tpl');
    const templateContent = fs.readFileSync(templatePath, 'utf8');

    // 替换占位符
    const replacedContent = templateContent
        .replace(/\$DB_NAME\$/g, dbname)
        .replace(/\$DB_USER\$/g, dbuser)
        .replace(/\$DB_PWD\$/g, dbpassword)
        .replace(/\$DB_HOST\$/g, dbhost)
        .replace(/\$TABLE_NAME\$/g, tableName)
        .replace(/\$PRIMARY\$/g, primarykey);

    // 生成新文件
    const outputFilePath = path.join(_routerfolder, `${tableName}.js`);
    fs.writeFileSync(outputFilePath, replacedContent, 'utf8');

    console.log(`已生成 ${tableName}.js 文件`);
    console.log('生成crud接口 end ');
}

function replaceContent(file, _contentreg, content) {
    console.log(file, _contentreg, content);
    try {
        // 读取文件内容
        let fileContent = fs.readFileSync(file, 'utf8');
        // 使用正则表达式查找并全局替换
        const replacedContent = fileContent.replace(new RegExp(_contentreg, 'g'), content);
        if (replacedContent !== fileContent) {
            // 将修改后的内容写回文件
            fs.writeFileSync(file, replacedContent, 'utf8');
            console.log('替换成功');
        } else {
            console.log(`未找到匹配项，无法替换`);
        }
    } catch (error) {
        console.error('文件操作出错:', error);
    }
}

function debugtest() {
    const sequelize = new Sequelize(dbname, dbuser, dbpassword, {
        host: dbhost,
        dialect: 'mysql'
    })
    const DataTypes = require("sequelize").DataTypes;
    var _obj = require('./project/apiserver/models/video.js');
    var obj = _obj(sequelize, DataTypes);
    generateFrontend('./project/frontend/', obj);
}

function main() {
    const args = process.argv.slice(2);
    if (args.length === 0) {
        console.log('请提供参数，可选参数: debug 或 init');
        return;
    }
    const command = args[0];
    if (command === 'debug') {
        debugtest();
    } else if (command === 'init') {
        init();
    } else {
        console.log('无效的参数，可选参数: debug 或 init');
    }
}

// 调用 main 函数
main();

// 移除之前的 debugtest() 和 init() 调用
// debugtest();
// init();


